package com.Java.train.member.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.Java.train.common.exception.BusniessException;
import com.Java.train.common.exception.BusniessExceptionEnum;
import com.Java.train.common.response.CommonResp;
import com.Java.train.common.utils.JwtUtil;
import com.Java.train.common.utils.SnowFlakeUtil;
import com.Java.train.member.domain.DTO.MemberDTO;
import com.Java.train.member.domain.Member;
import com.Java.train.member.mapper.MemberMapper;
import com.Java.train.member.req.MemberLoginReq;
import com.Java.train.member.req.MemberReq;
import com.Java.train.member.req.MemberSendCodeReq;
import com.Java.train.member.service.MemberService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import static com.Java.train.common.constant.RedisConstant.MEMBER_CODE;

@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {
    private static final Logger LOG = LoggerFactory.getLogger(MemberService.class);
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public CommonResp<Long> register(@Valid MemberReq memberReq) {
        String mobile = memberReq.getMobile();
        // 1.查询数据库中是否存在mobile
        Member member = getMember(mobile);

        if(ObjectUtil.isNotNull(member) || member != null){
            throw new BusniessException(BusniessExceptionEnum.MEMBER_MOBILE_EXITS);
        }
        // 2.不存在直接注册
        member = new Member();
        member.setId(SnowFlakeUtil.getSnowFlakeNextId());
        member.setMobile(mobile);
        save(member);
        return new CommonResp<Long>().ok(member.getId());
    }

    @Override
    public CommonResp<Long> sendCode(MemberSendCodeReq sendCodeReq) {
        // 1.获取并查询手机号
        String mobile = sendCodeReq.getMobile();
        Member member = getMember(mobile);
        // 2.手机号不存在，则存入数据库中
        if(ObjectUtil.isNull(member)){
            LOG.info("手机号不存在，已保存记录");
            member = new Member();
            member.setId(SnowFlakeUtil.getSnowFlakeNextId());
            member.setMobile(mobile);
            save(member);
        } else{
            LOG.info("手机号存在，不保存记录");
        }

        // 4.生成手机验证码
        Random random = new Random();
        String codeStr = "";
        for (int i = 0; i < 6; i++)
        {
            codeStr += random.nextInt(10);
        }
        long code = Long.parseLong(codeStr);
        LOG.info("验证码为：{}", code);
        String token = MEMBER_CODE + mobile;
        stringRedisTemplate.opsForValue().set(token, String.valueOf(code), 2, TimeUnit.MINUTES);
        LOG.info("手机验证码已经生成");
        // 3.改变短信验证信息
        LOG.info("改变短信保存信息");

        // 4.发送短信
        LOG.info("短信已发送");
        return new CommonResp<Long>().ok(code);
    }

    @Override
    public CommonResp<MemberDTO> login(MemberLoginReq memberLoginReq) {
        // 1.查询手机号是否存在（获取验证码时已经存储）
        String mobile = memberLoginReq.getMobile();
        String code = memberLoginReq.getCode();
        Member member = getMember(mobile);
        // 2.手机号不存在，抛枚举错误
        if(ObjectUtil.isNull(member)){
            throw new BusniessException(BusniessExceptionEnum.MEMBER_MOBILE_NOT_EXITS);
        }

        //3.获取redis中的验证码来判断
        String redis_token = MEMBER_CODE + mobile;
        String redis_code = stringRedisTemplate.opsForValue().get(redis_token);

        // 3.1 判断redis是否过期（为空），明确错误提升用户体验
        if(redis_code == null){
            throw new BusniessException(BusniessExceptionEnum.MEMBER_CODE_PASS_AWAY);
        }

        if(!code.equals(redis_code)){
            throw new BusniessException(BusniessExceptionEnum.MEMBER_MOBILE_CODE_ERROR);
        }
        // 4.1生成用户token信息
        String token = JwtUtil.createToken(member.getId(), member.getMobile());
        // 4.2校验成功，返回用户基本信息
        MemberDTO memberDTO = BeanUtil.copyProperties(member, MemberDTO.class);
        memberDTO.setToken(token);

        return new CommonResp<MemberDTO>().ok(memberDTO);
    }

    private Member getMember(String mobile) {
        LambdaQueryWrapper<Member> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        Member member = getOne(lambdaQueryWrapper.eq(Member::getMobile, mobile));
        return member;
    }
}
